package com.dbflow5.transaction;

import com.dbflow5.database.DatabaseWrapper;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import com.dbflow5.annotation.IntDef;

/**
 * Description: Provides transaction with priority. Meant to be used in a [PriorityTransactionQueue].
 */
public class PriorityTransactionWrapper implements ITransaction, Comparable<PriorityTransactionWrapper> {

    /**
     * Low priority requests, reserved for non-essential tasks
     */
    public static final int PRIORITY_LOW = 0;

    /**
     * The main of the requests, good for when adding a bunch of
     * data to the DB that the app does not access right away (default).
     */
    public static final int PRIORITY_NORMAL = 1;

    /**
     * Reserved for tasks that will influence user interaction, such as displaying data in the UI
     * some point in the future (not necessarily right away)
     */
    public static final int PRIORITY_HIGH = 2;

    /**
     * Reserved for only immediate tasks and all forms of fetching that will display on the UI
     */
    public static final int PRIORITY_UI = 5;

    private ITransaction<?> transaction;
    private int priority = PriorityTransactionWrapper.PRIORITY_NORMAL;

    public PriorityTransactionWrapper(ITransaction<?> transaction, int priority){
        this.transaction = transaction;
        this.priority = priority;
    }

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value = {PRIORITY_LOW, PRIORITY_NORMAL, PRIORITY_HIGH, PRIORITY_UI})
    public @interface Priority{

    }

    @Override
    public Void execute(DatabaseWrapper databaseWrapper) {
        transaction.execute(databaseWrapper);
        return null;
    }

    @Override
    public int compareTo(PriorityTransactionWrapper other) {
        return other.priority - priority;
    }

    public static PriorityTransactionWrapper withPriority(ITransaction<?> transaction, int priority) {
        return new PriorityTransactionWrapper(transaction, priority);
    }

}
